package com.ts.api.module.match.plan.internal.executor.handler;

import com.ts.api.module.api.convert.core.http.client.ApiHttpMessage;
import com.ts.api.module.api.entity.ApiUserRequest;
import com.ts.api.module.match.plan.internal.distribute.context.ApiPlanDistributeContext;
import com.ts.api.module.match.plan.internal.distribute.context.ChannelPlanDistributeContext;
import com.ts.api.module.match.plan.internal.distribute.handler.PlanDistributeHandler;
import com.ts.api.module.match.plan.internal.distribute.logger.PlanDistributeFlowLogger;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistribute;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistributeField;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistributePost;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistributeResult;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistributeUserRequest;
import com.ts.api.module.match.plan.internal.distribute.strategy.PlanDistributeStrategy;
import com.ts.api.module.match.plan.internal.executor.model.PlanExecuteTask;
import com.ts.api.module.match.plan.model.AbstractPlanMatch;
import com.ts.api.module.product.entity.po.ProductApplyFlowPO;
import com.ts.api.module.product.entity.po.ProductPO;
import com.ts.api.module.product.entity.po.ProductPlanPO;
import com.ts.api.module.product.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.Callable;

/**
 *  计划执行提交任务
 *
 *  @author Pan
 */
@Service
@Slf4j
public class PlanExecutorTaskHandler {

    @Autowired
    private PlanDistributeHandler distributeHandler;
    @Autowired
    private ProductService productService;
    @Autowired
    private ApiPlanDistributeContext apiPlanDistributeContext;
    @Autowired
    private ChannelPlanDistributeContext channelPlanDistributeContext;
    @Autowired
    private PlanDistributeFlowLogger planDistributeFlowLogger;

    /**
     *  同步方法-提交分发任务
     *
     *  @param  planExecuteTask  计划任务实体
     *  @return Callable         任务
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public PlanDistributeResult submitSync(PlanExecuteTask planExecuteTask) {
        //  业务参数
        String reqId = planExecuteTask.getReqId();
        ProductPlanPO distributePlan = planExecuteTask.getDistributePlan();
        ProductPO productPO = productService.get(distributePlan.getLoanProductId());
        ApiUserRequest apiUserRequest = planExecuteTask.getSourceApiUserRequest();
        AbstractPlanMatch abstractPlanMatch = planExecuteTask.getAbstractPlanMatch();

        //  构建请求参数
        PlanDistributeUserRequest planDistributeUserRequest = PlanDistributeUserRequest.ofCopy(apiUserRequest);
        //  构建撞库日志
        ProductApplyFlowPO startDistributeFlow = planDistributeFlowLogger.startDataExchangeFlow(planDistributeUserRequest, productPO, distributePlan, reqId);

        //  获取分发器类型-自有渠道/API渠道
        PlanDistributeStrategy distributeContext;
        if (abstractPlanMatch.hasApiChannel()) {
            distributeContext = apiPlanDistributeContext.getContext(productPO, distributePlan);
        } else {
            distributeContext = channelPlanDistributeContext.getContext(productPO, distributePlan);
        }

        //  构建分发对象
        PlanDistribute planDistribute = PlanDistribute.of(abstractPlanMatch, productPO, distributePlan, planDistributeUserRequest, startDistributeFlow, reqId);

        //  前置处理
        PlanDistributeResult preResult = distributeHandler.preHandle(planDistribute, distributeContext);
        if (!preResult.getDistributeStatus()) {
            return preResult;
        }

        //  执行分发流程
        PlanDistributeResult distributeResult = distributeHandler.distributeHandle(planDistribute, distributeContext);
        if (!distributeResult.getDistributeStatus()) {
            return distributeResult;
        }

        //  解析响应结果
        ApiHttpMessage apiHttpMessage = distributeResult.getApiHttpMessage();
        PlanDistributeField planDistributeField = distributeHandler.parseResponseHandle(planDistribute, apiHttpMessage, distributeContext);
        if (!planDistributeField.getParseStatus()) {
            PlanDistributeResult planDistributeResult = PlanDistributeResult.ofFail(planDistribute);
            planDistributeResult.setBizErrorMsg(planDistributeField.getBizErrorMsg());
            return planDistributeResult;
        }

        //  后置处理
        PlanDistributePost planDistributePost = PlanDistributePost.of(planDistribute, planDistributeField);
        PlanDistributeResult postResult = distributeHandler.postHandle(planDistributePost, distributeContext);
        if (!postResult.getDistributeStatus()) {
            return postResult;
        }

        //  修改当前分发流程状态为成功
        return postResult.modifyDistributeFlowSuc();
    }

    /**
     *  提交分发任务
     *
     *  @param  planExecuteTask  计划任务实体
     *  @return Callable         任务
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public Callable<PlanDistributeResult> submit(PlanExecuteTask planExecuteTask) {
        return () -> {
            //  业务参数
            String reqId = planExecuteTask.getReqId();
            ProductPlanPO distributePlan = planExecuteTask.getDistributePlan();
            ProductPO productPO = productService.get(distributePlan.getLoanProductId());
            ApiUserRequest apiUserRequest = planExecuteTask.getSourceApiUserRequest();
            AbstractPlanMatch abstractPlanMatch = planExecuteTask.getAbstractPlanMatch();

            //  构建请求参数
            PlanDistributeUserRequest planDistributeUserRequest = PlanDistributeUserRequest.ofCopy(apiUserRequest);
            //  构建撞库日志
            ProductApplyFlowPO startDistributeFlow = planDistributeFlowLogger.startDataExchangeFlow(planDistributeUserRequest, productPO, distributePlan, reqId);

            //  获取分发器类型-API渠道/自有渠道
            PlanDistributeStrategy distributeContext;
            if (abstractPlanMatch.hasApiChannel()) {
                distributeContext = apiPlanDistributeContext.getContext(productPO, distributePlan);
            } else {
                distributeContext = channelPlanDistributeContext.getContext(productPO, distributePlan);
            }

            //  构建分发对象
            PlanDistribute planDistribute = PlanDistribute.of(abstractPlanMatch, productPO, distributePlan, planDistributeUserRequest, startDistributeFlow, reqId);

            //  前置处理
            PlanDistributeResult preResult = distributeHandler.preHandle(planDistribute, distributeContext);
            if (!preResult.getDistributeStatus()) {
                return preResult;
            }

            //  执行分发流程
            PlanDistributeResult distributeResult = distributeHandler.distributeHandle(planDistribute, distributeContext);
            if (!distributeResult.getDistributeStatus()) {
                return distributeResult;
            }

            //  解析响应结果
            ApiHttpMessage apiHttpMessage = distributeResult.getApiHttpMessage();
            PlanDistributeField planDistributeField = distributeHandler.parseResponseHandle(planDistribute, apiHttpMessage, distributeContext);
            if (!planDistributeField.getParseStatus()) {
                PlanDistributeResult planDistributeResult = PlanDistributeResult.ofFail(planDistribute);
                planDistributeResult.setBizErrorMsg(planDistributeField.getBizErrorMsg());
                return planDistributeResult;
            }

            //  后置处理
            PlanDistributePost planDistributePost = PlanDistributePost.of(planDistribute, planDistributeField);
            PlanDistributeResult postResult = distributeHandler.postHandle(planDistributePost, distributeContext);
            if (!postResult.getDistributeStatus()) {
                return postResult;
            }

            //  修改当前分发流程状态为成功
            return postResult.modifyDistributeFlowSuc();
        };
    }
}
